#! /usr/bin/env python
#coding=utf-8

import os
import sys
import pprint
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../"))

from utils import ResterHelper
from utils import ResterStringBuilder

STARTUP_CONFIG_SERVICE_KEYS = ("name", "path", "uid", "gid", "once", "console", "notify_state", "on_demand",
        "sandbox", "disabled", "critical_enable", "limit_time", "limit_count", "importance", "caps",
        "cpu_core", "write_pid", "d_caps", "permission", "permission_acls", "apl", "secon",
        "start_mode", "boot_job", "start_job", "stop_job", "restart_job")

SERVICE_SHOW_KEYS = ("name", "path", "uid", "gid", "on_demand", "secon", "start_mode")

STARTUP_CONFIG_JOB_KEYS = ("name", "cmd_num", "service_num", "spend_time")

STARTUP_CONFIG_SOCKET_KEYS = ("name", "family", "type", "protocol", "permissions", "uid", "gid", "option")

STARTUP_CONFIG_CMD_KEYS = ("name", "content")

class ProcessResults(ResterStringBuilder):
    def __init__(self, keys, row, configMgr):
        for idx, key in enumerate(keys):
            self[key] = row[idx]

class ProcessServiceResults(ResterStringBuilder):
    def __init__(self, keys, row):
        for idx, key in enumerate(keys):
            self[key] = row[idx]
    def getStr(self, xargs=None, keys=None):
        ordered_keys = SERVICE_SHOW_KEYS
        return ResterStringBuilder.getStr(self, xargs, ordered_keys)
class ProcessServiceResultsSingle(ResterStringBuilder):
    def __init__(self, keys, row):
        for idx, key in enumerate(keys):
            self[key] = row[idx]
    def getStr(self, xargs=None, keys=None):
        ordered_keys = STARTUP_CONFIG_SERVICE_KEYS + ("socket_num",)
        return ResterStringBuilder.getStr(self, xargs, ordered_keys)

class ProcessServiceSocket(ResterStringBuilder):
    def __init__(self, keys, row):
        for idx, key in enumerate(keys):
            self[key] = row[idx]
    def getStr(self, xargs=None, keys=None):
        ordered_keys = STARTUP_CONFIG_SOCKET_KEYS
        return ResterStringBuilder.getStr(self, xargs, ordered_keys)

class ProcessJobCmdResults(ResterStringBuilder):
    def __init__(self, keys, row):
        for idx, key in enumerate(keys):
            self[key] = row[idx]
    def getStr(self, xargs=None, keys=None):
        ordered_keys = STARTUP_CONFIG_CMD_KEYS
        return ResterStringBuilder.getStr(self, xargs, ordered_keys)

class ProcessJobResults(ResterStringBuilder):
    def __init__(self, keys, row, product):
        for idx, key in enumerate(keys):
            self[key] = row[idx]
    def getStr(self, xargs=None, keys=None):
        ordered_keys = STARTUP_CONFIG_JOB_KEYS
        return ResterStringBuilder.getStr(self, xargs, ordered_keys)

class ProcessCmdResults(ProcessResults):
    def __init__(self, keys, row, product):
        ProcessResults.__init__(self, keys, row, product)

    def getStr(self, xargs=None, keys=None):
        ordered_keys = STARTUP_CONFIG_CMD_KEYS
        return ProcessResults.getStr(self, xargs, ordered_keys)

class StartupConfigRestMgr(object):
    def __init__(self, product):
        self._product = product
        self._files = self.get_names("config_file", ("fileId", "fileName"))
        self._jobs = self.get_names("config_job", ("jobId", "name"))
        self._services = self.get_names("config_service", ("serviceId", "name"))

    def get_names(self, tableName, keys):
        sqlcmd = "select %s from %s " % (", ".join(keys), tableName)
        cursor = self._product.getCursor()
        cursor.execute(sqlcmd)
        values = {}
        for row in cursor:
            values[row[1]] = row[0]
        return values

    def get_all(self, xargs=None):
        if xargs and xargs.get("config-type"):
            if (xargs["config-type"] == "jobs") :
                return self.doGetAllJob("config_job", STARTUP_CONFIG_JOB_KEYS)
            else:
                return self.doGetAllService("config_service", SERVICE_SHOW_KEYS)
        else:
            return self.doGetAllService("config_service", SERVICE_SHOW_KEYS)

    def doGetAllService(self, tableName, keys):
        sqlcmd = "select %s from %s " % (", ".join(keys), tableName)
        try:
            cursor = self._product.getCursor()
            cursor.execute(sqlcmd)
            processes = []
            for row in cursor:
                processes.append(ProcessServiceResults(keys, row))
        except Exception as e:
            print("Error ", e)
        return processes
    def doGetOneService(self, tableName, keys, name):
        sqlcmd = "select %s from %s where name=\"%s\"" % (", ".join(keys), tableName, name)
        try:
            cursor = self._product.getCursor()
            cursor.execute(sqlcmd)
            processes = []
            for row in cursor:
                processes.append(ProcessServiceResultsSingle(keys, row))
            sqlcmd = "select count(1) from config_service_socket inner join config_service on \
                config_service.serviceId=config_service_socket.serviceId where config_service.name=\"%s\"" \
                % (name)
            cursor.execute(sqlcmd)
            for row in cursor:
                processes[0]["socket_num"] = row[0]
                print(processes[0]["socket_num"])
        except Exception as e:
            print("Error ", e)
        return processes

    def doGetOneServiceSockets(self, tableName, keys, serviceId):
        sqlcmd = "select %s from %s where serviceId=\"%s\"" % (", ".join(keys), tableName, serviceId)
        try:
            cursor = self._product.getCursor()
            cursor.execute(sqlcmd)
            processes = []
            for row in cursor:
                processes.append(ProcessServiceSocket(keys, row))
        except Exception as e:
            print("Error ", e)
        return processes

    def doGetOneJobCmd(self, tableName, keys, name):
        sqlcmd = "select %s from %s where jobId=\"%s\" and name != \"start\"" % (", ".join(keys), tableName, name)
        try:
            cursor = self._product.getCursor()
            cursor.execute(sqlcmd)
            processes = []
            for row in cursor:
                processes.append(ProcessJobCmdResults(keys, row))
        except Exception as e:
            print("Error ", e)
        return processes

    def doGetOneJobService(self, tableName, keys, name):
        sqlcmd = "select %s from %s where jobId=\"%s\" and name = \"start\"" \
            % (", ".join(keys), tableName, name)
        try:
            cursor = self._product.getCursor()
            cursor.execute(sqlcmd)
            processes = []
            for row in cursor:
                processes.append(ProcessJobCmdResults(keys, row))
        except Exception as e:
            print("Error ", e)
        return processes

    def doGetAllJob(self, tableName, keys):
        bootStages = ("pre-init", "init", "post-init", "post-fs", "late-fs", "post-fs-data", "boot")
        processes = []
        cursor = self._product.getCursor()
        for idx, item in enumerate(bootStages):
            sqlcmd = "select name, (select count(1) as num from config_cmd where jobId=\"%d\" and name \
                not in(\"start\")) as cmd_num, (select count(1) as num from config_cmd where jobId=\"%d\" \
                and name=\"start\") as service_num, executionTime from config_job where name=\"%s\"" \
                % (idx + 1, idx + 1, item)
            cursor.execute(sqlcmd)
            for row in cursor:
                processes.append(ProcessJobResults(keys, row, self))
        return processes

    def doGetAllCmd(self, tableName, keys):
        sqlcmd = "select %s from %s " % (", ".join(keys), tableName)
        cursor = self._product.getCursor()
        cursor.execute(sqlcmd)
        processes = []
        for row in cursor:
            processes.append(ProcessCmdResults(keys, row, self))
        return processes

    def GetJobId(self, jobId):
        if self._jobs.get(jobId):
            return self._jobs.get(jobId)
        else:
            return "unknown"

    def GetServiceId(self, serviceId):
        if self._services.get(serviceId):
            return self._services.get(serviceId)
        else:
            return "unknown"

    def dbGetServiceInfo(self, serviceName, args):
        return self.doGetOneService("config_service", STARTUP_CONFIG_SERVICE_KEYS, serviceName)

    def dbGetSocketInfo(self, serviceName, args):
        return self.doGetOneServiceSockets("config_service_socket", STARTUP_CONFIG_SOCKET_KEYS,
            self.GetServiceId(serviceName))

    def dbGetJobCmdNum(self, jobName, args):
        return self.doGetOneJobCmd("config_cmd", STARTUP_CONFIG_CMD_KEYS, self.GetJobId(jobName))

    def dbGetJobStartServiceNum(self, jobName, args):
        return self.doGetOneJobService("config_cmd", STARTUP_CONFIG_CMD_KEYS, self.GetJobId(jobName))

    def doRestRequest(self, id, mod, args):
        mCmdMap = {
            'details':self.dbGetServiceInfo,
            'socket':self.dbGetSocketInfo,
            'cmdNum':self.dbGetJobCmdNum,
            'StartServiceNum':self.dbGetJobStartServiceNum
        }
        if mod in mCmdMap.keys():
            vals = mCmdMap[mod](id, args)
            return ResterHelper.build_array_content(vals, args)
        return ""

if __name__ == "__main__":
    import products

    product_mgr = products.Products()
    prod = product_mgr.get_product_by_name("openharmony", "rk3568")
    prod.load_db()

